﻿#nullable disable
using System;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyInjection.Extensions;
using NetMicro.EventBus.BackgroundServices;
using NetMicro.EventBus.Generators;
using NetMicro.EventBus.Internal;
using NetMicro.EventBus.Policies;
using NetMicro.EventBus.Publishers;
using NetMicro.EventBus.Rulers;
using NetMicro.EventBus.Serializers;
using NetMicro.EventBus.Trackers;

namespace NetMicro.EventBus
{
    public static class ServiceCollectionExtensions
    {


        /// <summary>
        /// 添加事件总线
        /// </summary>
        /// <param name="serviceCollection"></param>
        /// <returns></returns>
        public static IEventBusBuilder AddEventBus(this IServiceCollection serviceCollection, Action<EventBusOptions> busOptions = null)
        {
            if (busOptions != null)
            {
                serviceCollection.Configure(busOptions);
            }
            else
            {
                serviceCollection.Configure<EventBusOptions>(m => new EventBusOptions());
            }
            serviceCollection.TryAddSingleton<IMsgIdGenerator, GuidMsgIdGenerator>();
            serviceCollection.TryAddSingleton<IPublisherEvent, EventPublisher>();
            serviceCollection.TryAddSingleton<IMessageSerializer, JsonSerializer>();
            serviceCollection.TryAddSingleton<IEventHandlerInvoker, EventHandlerInvoker>();
            serviceCollection.TryAddSingleton<IEventNameRuler, DefaultNameRuler>();
            serviceCollection.TryAddSingleton<IEventHandlerNameRuler, EventHandlerNameRuler>();
            serviceCollection.TryAddSingleton<IEventHandlerFindProvider, EventHandlerFindProvider>();
            serviceCollection.TryAddSingleton<IMessageListener, MessageListener>();
            serviceCollection.AddSingleton<IHostedStopToken, InternalHostedStopToken>();
            serviceCollection.AddSingleton<IConsumerTracker, RedisTracker>();

            serviceCollection.AddSingleton<IMessageRetryServiceProvider, MessageRetryServiceProvider>();
            serviceCollection.AddSingleton<IEventRetryPolicy, EventRetryPolicy>();
            serviceCollection.AddSingleton<IEventErrorSendDeadLetter, EventErrorSendDeadLetter>();
            serviceCollection.AddSingleton<IEventErrorHandler, EventErrorHandler>();
            serviceCollection.AddSingleton<IPublisherDelayEvent, DelayEventPublisher>();
            serviceCollection.AddHostedService<EventBusStartup>();

            using ServiceProvider serviceProvider = serviceCollection.BuildServiceProvider();
            IEventHandlerFindProvider eventHandlerFindProvider = serviceProvider.GetRequiredService<IEventHandlerFindProvider>();
            System.Collections.Generic.IEnumerable<EventHandlerDescriptor> handlers = eventHandlerFindProvider.FindAll();
            foreach (EventHandlerDescriptor eventHandlerDescriptor in handlers)
                serviceCollection.AddTransient(eventHandlerDescriptor.EventHandlerType);

            return new EventBusBuilder(serviceCollection);
        }


     
    }
}